﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace WeiTap.Data.Utilities
{
    /// <summary>
    /// 翻页语句帮助类
    /// </summary>
    public class PagingHelper:IPagingHelper
    {
        /// <summary>
        /// 匹配查询列
        /// </summary>
        public Regex RegexColumns = new Regex(@"\A\s*SELECT\s+((?:\((?>\((?<depth>)|\)(?<-depth>)|.?)*(?(depth)(?!))\)|.)*?)(?<!,\s+)\bFROM\b",
            RegexOptions.IgnoreCase| RegexOptions.Multiline|RegexOptions.Singleline|RegexOptions.Compiled);
        /// <summary>
        /// 匹配Distinct语句
        /// </summary>
        public Regex RegexDistinct = new Regex(@"\ADISTINCT\s",
            RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.Compiled);
        /// <summary>
        /// 匹配OrderBy语句
        /// </summary>
        public Regex RegexOrderBy =
            new Regex(
                @"\bORDER\s+BY\s+(?!.*?(?:\)|\s+)AS\s)(?:\((?>\((?<depth>)|\)(?<-depth>)|.?)*(?(depth)(?!))\)|[\[\]`""\w\(\)\.])+(?:\s+(?:ASC|DESC))?(?:\s*,\s*(?:\((?>\((?<depth>)|\)(?<-depth>)|.?)*(?(depth)(?!))\)|[\[\]`""\w\(\)\.])+(?:\s+(?:ASC|DESC))?)*",
                RegexOptions.RightToLeft | RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.Compiled);
        /// <summary>
        /// PagingHelper的单利模式
        /// </summary>
        public static PagingHelper Instance { get; private set; }
        static PagingHelper() {
            Instance = new PagingHelper();
        }
        public bool SplitSQL(string sql, out SQLParts parts)
        {
            parts.Sql = sql;
            parts.SqlSelectRemoved = null;
            parts.SqlCount = null;
            parts.SqlOrderBy = null;
            //获取结果 select **** from
            var m = RegexColumns.Match(sql);
            if (!m.Success) return false;

            #region 把所有的列名替换为count(*)
            var g = m.Groups[1];
            parts.SqlSelectRemoved = sql.Substring(g.Index);
            if (RegexDistinct.IsMatch(parts.SqlSelectRemoved))
                parts.SqlCount = sql.Substring(0, g.Index) + " COUNT(" + m.Groups[1].ToString().Trim() + ") " + sql.Substring(g.Index + g.Length);
            else
                parts.SqlCount = sql.Substring(0, g.Index) + " COUNT(*) " + sql.Substring(g.Index + g.Length);
            #endregion
            m = RegexOrderBy.Match(parts.SqlCount);
            if (m.Success) {
                g = m.Groups[0];
                parts.SqlOrderBy = g.ToString();
                parts.SqlCount = parts.SqlCount.Substring(0, g.Index) + parts.SqlCount.Substring(g.Index + g.Length);
            }
            return true;
        }
    } 
}
